"""
基础配置管理模块
==============

从 shared/core/config/unified_config.py 提取的无依赖配置功能。
提供最基础的配置加载和管理功能，不依赖其他内部模块。
"""

import os
from typing import Dict, Any, Optional, Union, Type, List
from functools import lru_cache
from pathlib import Path
from dotenv import load_dotenv
from enum import Enum
import logging

try:
    # Pydantic v2: BaseSettings移到了pydantic-settings包
    from pydantic_settings import BaseSettings, SettingsConfigDict
    from pydantic import Field, validator
except ImportError:
    try:
        # 向后兼容旧版本的Pydantic
        from pydantic import BaseSettings, Field, validator
        SettingsConfigDict = None
    except ImportError:
        # 完全回退方案
        class BaseSettings:
            def model_dump(self):
                return {}
        def Field(*args, **kwargs):
            return None
        def validator(*args, **kwargs):
            def decorator(func):
                return func
            return decorator
        SettingsConfigDict = None

logger = logging.getLogger(__name__)


class ConfigAccessMode(Enum):
    """配置访问模式"""
    DICT = "dict"           # 字典式访问（向后兼容）
    OBJECT = "object"       # 对象式访问
    TYPED = "typed"         # 类型安全访问


class ServiceType(Enum):
    """服务类型枚举"""
    API_GATEWAY = "api-gateway"
    AUTH_SERVICE = "auth-service"
    USER_SERVICE = "user_service"
    TRADING_SERVICE = "trading-service"
    MARKET_DATA_SERVICE = "market-data-service"
    STRATEGY_SERVICE = "strategy-service"
    NOTIFICATION_SERVICE = "notification-service"
    MONITORING_SERVICE = "monitoring-service"


class RedFireConfigBase(BaseSettings):
    """RedFire配置基类"""
    
    # 服务信息
    service_name: str = Field(..., description="服务名称")
    service_version: str = Field("1.0.0", description="服务版本")
    environment: str = Field("development", description="运行环境")
    debug: bool = Field(False, description="调试模式")
    
    # 服务器配置
    host: str = Field("0.0.0.0", description="服务主机")
    port: int = Field(8000, description="服务端口")
    workers: int = Field(1, description="工作进程数")
    
    # 数据库配置
    postgres_host: str = Field("localhost", description="PostgreSQL主机")
    postgres_port: int = Field(5432, description="PostgreSQL端口")
    postgres_db: str = Field("redfire_analytics", description="PostgreSQL数据库")
    postgres_user: str = Field("redfire_analytics", description="PostgreSQL用户")
    postgres_password: str = Field("redfire_pg_2025", description="PostgreSQL密码")
    
    # MySQL配置
    mysql_host: str = Field("localhost", description="MySQL主机")
    mysql_port: int = Field(3307, description="MySQL端口")
    mysql_db: str = Field("redfire_trading", description="MySQL数据库")
    mysql_user: str = Field("redfire_app", description="MySQL用户")
    mysql_password: str = Field("redfire_app_2025", description="MySQL密码")
    
    # MongoDB配置
    mongodb_host: str = Field("localhost", description="MongoDB主机")
    mongodb_port: int = Field(27017, description="MongoDB端口")
    mongodb_db: str = Field("redfire", description="MongoDB数据库")
    mongodb_user: str = Field("redfire_user", description="MongoDB用户")
    mongodb_password: str = Field("password", description="MongoDB密码")
    
    # InfluxDB配置
    influxdb_url: str = Field("http://localhost:8086", description="InfluxDB URL")
    influxdb_token: str = Field("", description="InfluxDB Token")
    influxdb_org: str = Field("redfire", description="InfluxDB组织")
    influxdb_bucket: str = Field("trading_data", description="InfluxDB存储桶")
    
    # Redis配置
    redis_host: str = Field("localhost", description="Redis主机")
    redis_port: int = Field(6379, description="Redis端口")
    redis_db: int = Field(0, description="Redis数据库")
    redis_password: Optional[str] = Field("redfire_redis_2025", description="Redis密码")
    
    # RabbitMQ配置
    rabbitmq_host: str = Field("localhost", description="RabbitMQ主机")
    rabbitmq_port: int = Field(5672, description="RabbitMQ端口")
    rabbitmq_user: str = Field("guest", description="RabbitMQ用户")
    rabbitmq_password: str = Field("guest", description="RabbitMQ密码")
    rabbitmq_vhost: str = Field("/", description="RabbitMQ虚拟主机")
    
    # JWT配置
    jwt_secret_key: str = Field("redfire-default-jwt-secret-key-32chars", description="JWT密钥")
    jwt_algorithm: str = Field("HS256", description="JWT算法")
    jwt_access_token_expire_minutes: int = Field(30, description="访问令牌过期时间")
    jwt_refresh_token_expire_days: int = Field(7, description="刷新令牌过期时间")
    
    # 日志配置
    log_level: str = Field("INFO", description="日志级别")
    log_format: str = Field("json", description="日志格式")
    log_dir: str = Field("./logs", description="日志目录")
    
    # 安全配置
    cors_origins: str = Field("http://localhost:3000", description="CORS允许源（逗号分隔）")
    allowed_hosts: str = Field("localhost,127.0.0.1", description="允许的主机（逗号分隔）")
    
    # 监控配置
    enable_metrics: bool = Field(True, description="是否启用指标收集")
    metrics_path: str = Field("/metrics", description="指标路径")
    prometheus_port: int = Field(9090, description="Prometheus端口")
    grafana_port: int = Field(3000, description="Grafana端口")
    health_check_port: int = Field(9000, description="健康检查端口")
    metrics_port: int = Field(9100, description="指标端口")
    
    # 应用信息
    app_name: str = Field("RedFire Platform", description="应用名称")
    app_version: str = Field("1.0.0", description="应用版本")
    secret_key: str = Field("default-secret-key", description="应用密钥")

    if SettingsConfigDict:
        model_config = SettingsConfigDict(
            env_file=".env",
            env_prefix="REDFIRE_",
            case_sensitive=True,
            extra="allow"
        )

    @validator("jwt_secret_key")
    def validate_jwt_secret(cls, v):
        if len(v) < 32:
            raise ValueError("JWT密钥长度至少32个字符")
        return v
    
    @validator("environment")
    def validate_environment(cls, v):
        allowed = ["development", "testing", "staging", "production"]
        if v not in allowed:
            raise ValueError(f"环境必须是: {', '.join(allowed)}")
        return v
    
    @validator("log_level")
    def validate_log_level(cls, v):
        allowed = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
        if v.upper() not in allowed:
            raise ValueError(f"日志级别必须是: {', '.join(allowed)}")
        return v.upper()
    
    @property
    def is_production(self) -> bool:
        return self.environment.lower() == "production"
    
    @property
    def is_development(self) -> bool:
        return self.environment.lower() == "development"
    
    @property
    def is_testing(self) -> bool:
        return self.environment.lower() == "testing"


class RedFireConfigManager:
    """RedFire配置管理器"""
    
    def __init__(self):
        self._configs: Dict[str, Any] = {}
        self._access_mode = ConfigAccessMode.DICT
    
    @lru_cache()
    def get_service_config(
        self, 
        service_name: str, 
        access_mode: ConfigAccessMode = ConfigAccessMode.DICT
    ) -> Union[Dict[str, Any], RedFireConfigBase]:
        """获取服务配置"""
        
        # 加载配置文件
        self._load_config_files(service_name)
        
        # 创建服务特定的配置类
        service_config_class = self._create_service_config_class(service_name)
        config_instance = service_config_class()
        
        if access_mode == ConfigAccessMode.DICT:
            return self._convert_to_dict(config_instance, service_name)
        elif access_mode == ConfigAccessMode.OBJECT:
            return config_instance
        else:
            return config_instance
    
    def _load_config_files(self, service_name: str) -> None:
        """加载配置文件，支持分层配置"""
        # 尝试从多个位置加载配置
        config_paths = [
            Path(__file__).parent.parent / "core" / "config",
            Path(__file__).parent / "config",
            Path.cwd() / "config",
            Path.cwd()
        ]
        
        for config_dir in config_paths:
            if config_dir.exists():
                # 加载基础配置
                base_config_path = config_dir / "base.env"
                if base_config_path.exists():
                    load_dotenv(base_config_path, override=False)
                
                # 加载服务特定配置
                if service_name and service_name != "default":
                    service_config_path = config_dir / "services" / f"{service_name}.env"
                    if service_config_path.exists():
                        load_dotenv(service_config_path, override=True)
                break
    
    def _create_service_config_class(self, service_name: str) -> Type[RedFireConfigBase]:
        """为特定服务创建配置类"""
        
        # 服务端口映射
        service_ports = {
            "api-gateway": 8000,
            "auth_service": 8005,
            "user_service": 8001,
            "trading_service": 8002,
            "market_data_service": 8003,
            "strategy_service": 8004,
            "notification_service": 8006,
            "monitoring_service": 8007,
        }
        
        default_port = service_ports.get(service_name, 8000)
        service_prefix = service_name.upper().replace('-', '_')
        
        # 捕获变量到本地作用域
        _service_name = service_name
        _default_port = default_port
        _service_prefix = service_prefix
        
        class ServiceConfig(RedFireConfigBase):
            service_name: str = Field(default=_service_name, description="服务名称")
            port: int = Field(default=_default_port, description="服务端口")
            
            if SettingsConfigDict:
                model_config = SettingsConfigDict(
                    env_file=".env",
                    env_prefix=f"REDFIRE_{_service_prefix}_",
                    case_sensitive=True,
                    extra="allow"
                )
        
        return ServiceConfig
    
    def _convert_to_dict(self, config: RedFireConfigBase, service_name: str) -> Dict[str, Any]:
        """将配置对象转换为字典（向后兼容）"""
        config_dict = config.model_dump()
        
        # 构建Redis URL
        redis_auth = f":{config_dict['redis_password']}@" if config_dict['redis_password'] else ""
        redis_url = f"redis://{redis_auth}{config_dict['redis_host']}:{config_dict['redis_port']}/{config_dict['redis_db']}"
        
        # 重组为原有的嵌套结构
        return {
            "service_name": service_name,
            "app_name": config_dict["app_name"],
            "app_version": config_dict["app_version"],
            "environment": config_dict["environment"],
            "debug": config_dict["debug"],
            "secret_key": config_dict["secret_key"],
            
            "server": {
                "host": config_dict["host"],
                "port": config_dict["port"],
                "health_check_port": config_dict["health_check_port"],
                "metrics_port": config_dict["metrics_port"],
            },
            
            "database": {
                "postgres": {
                    "host": config_dict["postgres_host"],
                    "port": config_dict["postgres_port"],
                    "database": config_dict["postgres_db"],
                    "username": config_dict["postgres_user"],
                    "password": config_dict["postgres_password"],
                },
                "mysql": {
                    "host": config_dict["mysql_host"],
                    "port": config_dict["mysql_port"],
                    "database": config_dict["mysql_db"],
                    "username": config_dict["mysql_user"],
                    "password": config_dict["mysql_password"],
                },
                "mongodb": {
                    "host": config_dict["mongodb_host"],
                    "port": config_dict["mongodb_port"],
                    "database": config_dict["mongodb_db"],
                    "username": config_dict["mongodb_user"],
                    "password": config_dict["mongodb_password"],
                },
                "influxdb": {
                    "url": config_dict["influxdb_url"],
                    "token": config_dict["influxdb_token"],
                    "org": config_dict["influxdb_org"],
                    "bucket": config_dict["influxdb_bucket"],
                }
            },
            
            "redis": {
                "host": config_dict["redis_host"],
                "port": config_dict["redis_port"],
                "password": config_dict["redis_password"],
                "db": config_dict["redis_db"],
                "url": redis_url,
            },
            
            "jwt": {
                "secret_key": config_dict["jwt_secret_key"],
                "algorithm": config_dict["jwt_algorithm"],
                "access_token_expire_minutes": config_dict["jwt_access_token_expire_minutes"],
                "refresh_token_expire_days": config_dict["jwt_refresh_token_expire_days"],
            },
            
            "logging": {
                "level": config_dict["log_level"],
                "format": config_dict["log_format"],
                "dir": config_dict["log_dir"],
                "service_prefix": service_name.upper().replace('-', '_'),
            },
            
            "security": {
                "cors_origins": config_dict["cors_origins"].split(","),
                "allowed_hosts": config_dict["allowed_hosts"].split(","),
            },
            
            "monitoring": {
                "enabled": config_dict["enable_metrics"],
                "metrics_path": config_dict["metrics_path"],
                "prometheus_port": config_dict["prometheus_port"],
                "grafana_port": config_dict["grafana_port"],
            }
        }


# 全局配置管理器实例
config_manager = RedFireConfigManager()

# BaseServiceConfig 集成
from dataclasses import dataclass

@dataclass
class ServiceMetadata:
    """服务元数据"""
    name: str
    version: str = "1.0.0"
    description: str = ""
    maintainer: str = "RedFire Team"


class BaseServiceConfig:
    """基础服务配置类"""
    
    def __init__(self, service_name: str):
        self.service_name = service_name
        self._config_data = config_manager.get_service_config(service_name, ConfigAccessMode.DICT)
        self._typed_config = config_manager.get_service_config(service_name, ConfigAccessMode.TYPED)
    
    @property
    def config(self) -> Dict[str, Any]:
        """获取完整配置字典"""
        return self._config_data
    
    @property
    def service_metadata(self) -> ServiceMetadata:
        """获取服务元数据"""
        return ServiceMetadata(
            name=self.service_name,
            version=self._config_data.get("app_version", "1.0.0"),
            description=f"{self.service_name} microservice",
            maintainer="RedFire Team"
        )
    
    @property
    def debug(self) -> bool:
        """是否调试模式"""
        return self._config_data.get("debug", False)
    
    @property
    def environment(self) -> str:
        """运行环境"""
        return self._config_data.get("environment", "development")
    
    def get_config_value(self, key: str, default: Any = None) -> Any:
        """获取配置值，支持点号分隔的嵌套键"""
        keys = key.split('.')
        value = self._config_data
        
        for k in keys:
            if isinstance(value, dict) and k in value:
                value = value[k]
            else:
                return default
        
        return value


# 模块级别的便捷函数
def get_service_config(service_name: str, access_mode: ConfigAccessMode = ConfigAccessMode.DICT) -> Union[Dict[str, Any], RedFireConfigBase]:
    """获取服务配置的便捷函数"""
    return config_manager.get_service_config(service_name, access_mode)


def get_service_config_typed(service_name: str) -> RedFireConfigBase:
    """获取类型化的服务配置"""
    return config_manager.get_service_config(service_name, ConfigAccessMode.TYPED)


def get_service_config_object(service_name: str) -> RedFireConfigBase:
    """获取配置对象"""
    return config_manager.get_service_config(service_name, ConfigAccessMode.OBJECT)


# 导出主要接口
__all__ = [
    "get_service_config",
    "get_service_config_typed", 
    "get_service_config_object",
    "BaseServiceConfig",
    "ServiceMetadata",
    "RedFireConfigBase",
    "RedFireConfigManager",
    "ConfigAccessMode",
    "ServiceType"
]
